'use strict'

process.chdir(__dirname)

const titbit = require('titbit')
const tbloader = require('titbit-loader')
const {resource, mixlogger} = require('titbit-toolkit')
const config = require('./config/config.js')
const funcs = require('./lib/funcs')
const database = require('./config/database.js')
const cdpc = require('cdpc')
const npargv = require('npargv')
const fs = require('fs')
const httpc = require('titbit-httpc')

const {args} = npargv({
  '@autoDefault': true,

  '--test' : {
    name: 'test',
    default: false,
  },

  '--debug' : {
    name: 'debug',
    default: false,
  },
})

let loadfile = '/tmp/nodeapp-load.log'

if (process.platform.indexOf('win') === 0) {
  loadfile = __dirname + '/tmp/nodeapp-load.log'
}

if (config.httpCompatible) {
  config.http2 = false
  config.https = true
}

const app = new titbit({
  debug: args.debug,
  maxUrlLength: 4096,
  maxQuery: 50,
  monitorTimeSlice: 172,
  loadInfoFile: loadfile,
  loadInfoType: 'json',
  https: config.https,
  http2: config.http2,
  cert: (config.https || config.http2 )? config.cert : '',
  key: (config.https || config.http2 )? config.key : '',
  server: {
    handshakeTimeout: 10000
  },
  maxLoadRate: 62,

  //启用全局日志
  globalLog: true,

  logType: 'file',
  logFile: './tmp/success.log',
  errorLogFile: './tmp/error.log',
  
  //日志文件最大条数
  logMaxLines: 10000,

  //最大历史日志文件数量
  logHistory: 50,
})

if (config.httpCompatible) {
  ;(new httpc).init(app)
}

if (config.autoWorker > 0 && config.autoWorker > config.worker) {
  app.autoWorker(config.autoWorker)
}

if (app.isMaster) {
  ;(new mixlogger({
    logHandle: (w, msg, handle) => {
      if (msg.log.indexOf('/sys/loadinfo', 7) > 0) {
        return false
      }
    
      return true
    }
  })).init(app)

  try {
    fs.accessSync(__dirname + '/tmp')
  } catch (err) {
    fs.mkdirSync(__dirname + '/tmp')
  }

  [
    '/storage', 
    '/storage/images', 
    '/storage/audios', 
    '/storage/videos', 
    '/storage/files'
  ].forEach(a => {
    funcs.tryMkdir(__dirname + a).catch(err => {
      console.error(err)
    })
  })
}

if ((app.isWorker && config.cluster) || (!config.cluster && app.isMaster)) {
  app.addService('loadfile', loadfile)
  app.addService('DEBUG', args.debug)
  app.addService('TEST', args.test)

  app.addService('appDir', __dirname)
  app.addService('dataPath', `${__dirname}/data`)
  app.addService('storagePath', `${__dirname}/storage`)

  app.addService('config', config)
  app.addService('funcs', funcs)

  let appinit = require('./init.js')

  ;(typeof appinit === 'function') && appinit(app)

  if (config.loader.loadModel) {
    let pqorm = database.postgres.init()
    config.loader.mdb = pqorm
    app.addService('pqorm', pqorm)
  }

  let tbl = new tbloader(config.loader)
  
  tbl.init(app)

  let rse = new resource({
    staticPath: `${__dirname}/public/static`,
    routePath : '/static/*',
    routeGroup: '_static',
    decodePath: true,
  })
  
  rse.init(app)

  app.get('/favicon.ico', async c => {}, {group: '_static'})
  
  app.get('/', async c => {
    await c.helper.pipe('./public/index.html', c.reply)
  })

  app.get('/page/:name', async c => {
    try {
      await c.helper.pipe( `./public/${c.param.name}.html`, c.reply)
    } catch (err) {
      c.service.DEBUG && console.error(err)
      c.status(404)
      await c.helper.pipe( `./public/errorpages/404.html`, c.reply)
    }
  })

}

let port = 1234

if (config.cluster) {
  app.daemon(config.port || port, config.host || '::', config.worker)
} else {
  app.run(config.port || port, config.host || '::')
}
